﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;

namespace CommonLibraries.DeviceLibrary
{
    public class Camera : ICamera
    {
        private static Camera Instance = null;
        private static void CreateInstance()
        {
            if (Instance == null)
            {
                Instance = new Camera();
            }
        }
        public static Camera GetInstance()
        {
            if (Instance == null) CreateInstance();
            return Instance;
        }

        #region ICamera Members

        private int prop_ImageSize = 0;
        public int ImageSize
        {
            get { return prop_ImageSize; }
            set { prop_ImageSize = value; }
        }

        public event EventHandler PowerStateChanged;

        public int Brightness
        {
            get
            {
                int _brightness = default(int);
                TGMS2.TGMS2_GetCameraBright(ref _brightness);
                return _brightness;
            }
            set
            {
                int _brightness;
                _brightness = value;
                TGMS2.TGMS2_SetCameraBright(_brightness);
            }
        }

        public int Sharpness
        {
            get
            {
                int _sharpness = default(int);
                TGMS2.TGMS2_GetCameraBright(ref _sharpness);
                return _sharpness;
            }
            set
            {
                int _sharpness;
                _sharpness = value;
                TGMS2.TGMS2_SetCameraSharp((uint)_sharpness);
            }
        }

        public PowerStates PowerState
        {
            get
            {
                int _powerstate;
                _powerstate = TGMS2.TGMS2_GetCameraPowerState();
                return (_powerstate == 1 ? PowerStates.On : PowerStates.Off);
            }
            set
            {
                int _powerstate;
                _powerstate = (value == PowerStates.On ? 1 : 0);

                bool _Changed;
                _Changed = (value != this.PowerState);

                int status;
                status = TGMS2.TGMS2_SetCameraPowerState(_powerstate);

                if (_Changed && PowerStateChanged != null)
                    PowerStateChanged(this, new EventArgs());
            }
        }

        public CameraModes PictureMode
        {
            get
            {
                int _pwdLevel = 0;
                if (TGMS2.TGMS2_GetCameraAgainstSun() == 1)
                    return CameraModes.IntoSun;
                if (TGMS2.TGMS2_GetCameraNightMode(ref _pwdLevel) == 1)
                    return CameraModes.Night;
                return CameraModes.Normal;
            }
            set
            {
                switch (value)
                {
                    case CameraModes.Normal:
                        TGMS2.TGMS2_SetCameraNightMode((uint)TGMS2.TGMS2ENUM.TGMS2_CAMERA_GAIN_AUTO);
                        TGMS2.TGMS2_SetCameraAgainstSun(0);
                        break;
                    case CameraModes.IntoSun:
                        TGMS2.TGMS2_SetCameraNightMode((uint)TGMS2.TGMS2ENUM.TGMS2_CAMERA_GAIN_AUTO);
                        TGMS2.TGMS2_SetCameraAgainstSun(1);
                        break;
                    case CameraModes.Night:
                        TGMS2.TGMS2_SetCameraNightMode((uint)TGMS2.TGMS2ENUM.TGMS2_CAMERA_GAIN_NIGHT);
                        TGMS2.TGMS2_SetCameraAgainstSun(0);
                        break;
                    default:
                        throw new NotSupportedException(string.Format("Unsupported PictureMode {0}", value.ToString()));
                        break;
                }
            }
        }

        private ZoomLevels prop_Zoom = ZoomLevels.x1;

        public ZoomLevels Zoom
        {
            get
            {
                int _bzoom = default(int);
                if (_bzoom == TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_QQVGA))
                    prop_Zoom = ZoomLevels.x1;
                if (_bzoom == TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_QVGA))
                    prop_Zoom = ZoomLevels.x2;
                if (_bzoom == TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_VGA))
                    prop_Zoom = ZoomLevels.x4;
                return prop_Zoom;
            }
            set
            {
                switch (value)
                {
                    case ZoomLevels.x0:
                        prop_ImageSize = 0;
                        TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_SXGA);
                        break;
                    case ZoomLevels.x1:
                        prop_ImageSize = 1;
                        //TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_VGA);
                        TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_SXGA);
                        break;
                    case ZoomLevels.x2:
                        prop_ImageSize = 2;
                        //TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_QVGA);
                        TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_SXGA);
                        break;
                    case ZoomLevels.x4:
                        prop_ImageSize = 3;
                        //TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_VGA);
                        TGMS2.TGMS2_SetCameraFinderZoom((uint)TGMS2.TGMS2ENUM.TGMS2_OV_SXGA);
                        break;
                    default:
                        break;
                }
            }
        }

        public System.Drawing.Bitmap Overlay
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        private Bitmap m_Image;
        
        public System.Drawing.Bitmap TakePicture(double longitude, double latitude, double altitude, double bearing, int PDOP)
        {
            return m_Image;
        }
        
        private const int m_NumberOfSounds = 1;
       
        public bool SetSound(string soundPath)
        {
            int _SetSoundResult;
            _SetSoundResult = TGMS2.TGMS2_SetShutterSoundFile(soundPath, m_NumberOfSounds);
            return Convert.ToBoolean(_SetSoundResult);
        }
        #endregion

        protected void CreateDebug(string debugData)
        {
            StreamWriter _a = File.AppendText(".\\DebugClasses.txt");
            _a.WriteLine("##############################");
            _a.WriteLine(System.DateTime.Now.ToShortDateString() + " " + System.DateTime.Now.ToShortTimeString());
            _a.WriteLine("##############################");
            _a.WriteLine(debugData);
            _a.Close();
            _a.Dispose();

        }

        /// <summary>
        /// Power on the camera
        /// </summary>
        /// <param name="x">Position x picture box</param>
        /// <param name="y">Position y picture box</param>
        /// <returns></returns>
        public bool On(int x, int y)
        {
            try 
	        {
                PowerState = PowerStates.On;
                SetCameraFinder(1,x,y);
                return true;
	        }
	        catch (Exception ex)
	        {
                CreateDebug("Camera->On->"+ex.Message);
        		return false;
	        }
            
        }

        /// <summary>
        /// Only turns the camera on if it is turned off
        /// </summary>
        /// <returns></returns>
        public bool On()
        {
            try
            {
                if(PowerState == PowerStates.Off )
                    PowerState = PowerStates.On;
                return true;
            }
            catch (Exception ex)
            {
                CreateDebug("Camera->On->" + ex.Message);
                return false;
            }

        }

        /// <summary>
        /// Power off the camera
        /// </summary>
        /// <param name="x">Position x picture box</param>
        /// <param name="y">Position y picture box</param>
        /// <returns></returns>
        public bool Off(int x, int y)
        {
            try 
	        {
                SetCameraFinder(0, x, y);
	            PowerState = PowerStates.Off;
                return true;
        		
	        }
	        catch (Exception ex)
	        {
                CreateDebug("Camera->Off->"+ex.Message);
                return false;
	        }
        }

        /// <summary>
        /// Power off the camera
        /// </summary>
        /// <returns></returns>
        public bool Off()
        {
            try
            {
                if(PowerState == PowerStates.On) PowerState = PowerStates.Off;
                return true;
            }
            catch (Exception ex)
            {
                CreateDebug("Camera->Off->" + ex.Message);
                return false;
            }
        }

        /// <summary>
        /// Active/desactive Finder rectangle
        /// </summary>
        /// <param name="power">1 Active
        ///                     2 Desactive</param>
        /// <param name="y">Position y picture box</param>
        /// <param name="y">Position y picture box</param>
        /// <returns></returns>
        public bool SetCameraFinder(int power, int x, int y)
        {
            try 
	        {
                TGMS2.TGMS2_SetCameraFinder(power, (uint)x, (uint)y);
                return true;
	        }
	        catch (Exception ex)
	        {
        		CreateDebug("Camera->SetCameraFinder"+ex.Message);
		        return false;
	        }
        }

        public bool TakePhoto(string FileName, int Size)
        {
            try
            {
                TGMS2.CaptureImage(Size, FileName);
                return true;
            }
            catch (Exception ex) 
            {
                CreateDebug("Camera->TakePhoto" + ex.Message);
                return false;
            }
        }

        

    }

        
}
